package org.uds.android.fitdroid.demo.activity.spatial;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.StringTokenizer;

import org.uds.android.fitdroid.demo.apis.EventDataSQLHelper;
import org.uds.android.fitdroid.demo.apis.R;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class SQLDemo extends Activity implements LocationListener{
	
  private String latitude;
  private String longitude;
  private String altitude;
  private EventDataSQLHelper eventsData;
  private EditText resdistance;
  private EditText avgspeed;
  private EditText speedtest;
  private TextView output;
//  private TextView gpsdata; 
  private Button delete;
  private Button distance;
  private LocationManager locMgrGPS = null;
  private double currentdistance=0;
  private Location oldlocation=null;
  
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    output = (TextView) findViewById(R.id.output);
    output.setMovementMethod(new ScrollingMovementMethod());
    output.computeScroll();
 
    resdistance = (EditText) findViewById(R.id.calcDistance);
    
    avgspeed = (EditText) findViewById(R.id.Speed);
    
    speedtest = (EditText) findViewById(R.id.Speedtest);
    
  /*  gpsdata = (TextView) findViewById(R.id.gpsdata);
    gpsdata.setText("");
    gpsdata.setMovementMethod(new ScrollingMovementMethod());
    gpsdata.computeScroll();*/
    
    delete = (Button)findViewById(R.id.Delete);
    delete.setOnClickListener(mdeleteListener);
    
    distance = (Button)findViewById(R.id.Distance);
    distance.setOnClickListener(mdistanceListener);

    
    locMgrGPS = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
    // attr 2 = every x ms look for an update
    // attr 3 = every x meters position changing update
    locMgrGPS.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this);
    
    eventsData = new EventDataSQLHelper(this);
   // addEvent("First GPS Location");
    Cursor cursor = getEvents();
    showEvents(cursor);
  }
  
  @Override
  public void onDestroy() {	  
	  eventsData.close();
	  super.onDestroy();
  }

  private void addEvent(String title) {
    SQLiteDatabase db = eventsData.getWritableDatabase();
    
    //Gpsdata Table
    ContentValues values = new ContentValues();
    values.put(EventDataSQLHelper.LATITUDE, this.latitude); 
    values.put(EventDataSQLHelper.LONGITUDE, this.longitude);
    values.put(EventDataSQLHelper.ALTITUDE, this.altitude);
    values.put(EventDataSQLHelper.DATE, now ("yyyy.MM.dd"));
    values.put(EventDataSQLHelper.TIME, now("H:mm:ss"));
    Long gpsid=db.insert(EventDataSQLHelper.GPSDATA, null, values);
    
    //Tconstist table
    db = eventsData.getWritableDatabase();
    values = new ContentValues();
    values.put("trackid", 1);
    values.put("gpsdataid", gpsid);    
    db.insert(EventDataSQLHelper.TCONSITS, null, values);
    

  }

  private Cursor getEvents() {
    SQLiteDatabase db = eventsData.getReadableDatabase();
    Cursor cursor = db.query(EventDataSQLHelper.GPSDATA, null, null, null, null,
        null, null);
    
    startManagingCursor(cursor);
    return cursor;
  }

  private void showEvents(Cursor cursor) {
    StringBuilder ret = new StringBuilder("");
    while (cursor.moveToNext()) {
      long id = cursor.getLong(0);
      String latitude2 = cursor.getString(1);
      String longitude2 = cursor.getString(2);
      String altitude2 = cursor.getString(3);
      ret.append(id + "\n \t latitude " + latitude2 + "\n \t longitude :" + longitude2 + "\n \t altitude :" + altitude2 +"\n");
    }
    output.setText(ret);
  }

@Override
public void onLocationChanged(Location location) {
	// TODO Auto-generated method stub
    this.latitude = String.valueOf(location.getLatitude());
    this.longitude = String.valueOf(location.getLongitude());
    this.altitude = String.valueOf(location.getAltitude());
    addEvent("Update");
    speedtest.setText((location.getSpeed()*(3.6))+"km/h");
    if (oldlocation==null)
    {
    	oldlocation=location;
    	avgspeed.setText("0 km");
    	currentdistance=0;
    }
    else
    {
    	currentdistance+=(oldlocation.distanceTo(location)/1000);
    	oldlocation=location;
    	avgspeed.setText(currentdistance+"km");
    }
    
    	
    
    
    
   
    
   // this.gpsdata.append("\n\tLatitude: "+location.getLatitude() +"\n\tLongitude: " + location.getLongitude()+"\n\tAltitude: " + location.getAltitude()+"\n");
   /* Cursor cursor = getEvents();
    showEvents(cursor);*/
}

private OnClickListener mdeleteListener = new OnClickListener() {
    public void onClick(View v) {
      // do something when the button is clicked
    	SQLiteDatabase db = eventsData.getWritableDatabase();
    	db.delete(EventDataSQLHelper.GPSDATA, null, null);
    	
    	output.setText("");
    	Cursor cursor = getEvents();
        showEvents(cursor);
    }
};

private OnClickListener mdistanceListener = new OnClickListener() {
    public void onClick(View v) {
      // do something when the button is clicked
    	double[] res = calctrackdistance(1);
    	resdistance.setText(String.valueOf(res[0])+" km");
    	
    	//avgspeed.setText(String.valueOf(res[1])+" km/h");
    }
};


@Override
public void onProviderDisabled(String arg0) {
	// TODO Auto-generated method stub
	
}

@Override
public void onProviderEnabled(String arg0) {
	// TODO Auto-generated method stub
	
}

@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
	// TODO Auto-generated method stub
	
}

// returns total distance of a track
public double[] calctrackdistance (int Trackid)
{
	
	LinkedList<Integer> Gpsidset =new LinkedList<Integer>();
	Cursor cursor;
	double totaldistance =0;
	double time=0;
	int counter =0;
	
	String startlong = "";
	String startlati = "";
	String endlong = "";
	String endlati = "";
	
	// get all the gpsids
	SQLiteDatabase db = eventsData.getReadableDatabase();
	
	cursor = db.query(EventDataSQLHelper.TCONSITS, new String[]{"gpsdataid"}, "trackid="+Trackid, null, null,null, "_id");
	startManagingCursor(cursor);
	while (cursor.moveToNext()) {
		Gpsidset.add(cursor.getInt(0));
    }
	
	// check if there is still a point left to measure the distance
	while (counter+1<Gpsidset.size())
		{
			//get 2 points to calc the distance
			cursor = db.query(EventDataSQLHelper.GPSDATA, new String[]{"latitude","longitude"}, "_id="+Gpsidset.get(counter), null, null,null, null);
			startManagingCursor(cursor);
						
			while (cursor.moveToNext()) {
					startlati = cursor.getString(0);
					startlong = cursor.getString(1);
			    }
			
			cursor = db.query(EventDataSQLHelper.GPSDATA, new String[]{"latitude","longitude"}, "_id="+Gpsidset.get(counter+1), null, null,null, null);
			startManagingCursor(cursor);
			
			
			while (cursor.moveToNext()) {
					endlati = cursor.getString(0);
					endlong= cursor.getString(1);
			    }
			// add the distance to the totaldistance
			totaldistance += calcdistance (startlong,startlati,endlong,endlati); 
			
			counter++;
		}
	
	// calc Start+ End Time
	int timediff=0;
	if (Gpsidset.size()>1)
	{
		String starttime="";
		String startdate="";
		String endtime="";
		String enddate="";
		
		cursor = db.query(EventDataSQLHelper.GPSDATA, new String[]{"time","date"}, "_id="+Gpsidset.get(0), null, null,null, null);
		startManagingCursor(cursor);
					
		while (cursor.moveToNext()) {
				starttime = cursor.getString(0);
				startdate = cursor.getString(1);
		    }
		
		cursor = db.query(EventDataSQLHelper.GPSDATA, new String[]{"time","date"}, "_id="+Gpsidset.get(Gpsidset.size()-1), null, null,null, null);
		startManagingCursor(cursor);
					
		while (cursor.moveToNext()) {
				endtime = cursor.getString(0);
				enddate = cursor.getString(1);
		    }
		
		timediff = converttime(endtime)-converttime(starttime);
		timediff*=(60*60);
	}
	
	double[] res = new double[]{totaldistance,(totaldistance/timediff)};
	return res;   	
	
}



// returns distance in km between 2 points
public double calcdistance (String startlong, String startlati, String endlong, String endlati)
{
	double lon1 = Float.valueOf(startlong);
	double lon2 = Float.valueOf(endlong);
	
	double lat1 = Float.valueOf(startlati);
	double lat2 = Float.valueOf(endlati);
	
	double R = 6371; // km
	double dLat = Math.toRadians(lat2-lat1);
	double dLon = Math.toRadians(lon2-lon1); 
	double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
	        Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * 
	        Math.sin(dLon/2) * Math.sin(dLon/2); 
	double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
	double d = R * c;
	
	return d;
}

private String now(String dateFormat) {
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    return sdf.format(cal.getTime());

  }

private int converttime (String time)
{
	StringTokenizer tokenizer = new StringTokenizer(time,":");
	int counter =0;
	
	int res=0;
	while (tokenizer.hasMoreTokens())
	{
		if (counter==0)
		{
			res+= Integer.valueOf(tokenizer.nextToken())*60*60;
		}
		else
			if (counter==1)
			{
				res+= Integer.valueOf(tokenizer.nextToken())*60;
			}
			else
			{
				res+= Integer.valueOf(tokenizer.nextToken());
			}
	}
	return res;
}
}